﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using K9Nano.Application;
using K9Nano.AspNetCore.Api;
using K9Nano.Authentication;
using K9Nano.Authorization;
using K9Nano.Share;
using K9Nano.Share.Exceptions;
using K9Nano.Share.Extensions;
using K9Nano.Web.Accounts.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace K9Nano.Web.Accounts
{
    [ApiController]
    [Route("role/[action]")]
    [Authorize(Policy = K9SharedConstants.PolicyTenantAdmin)]
    public abstract class RoleController : CurdController<IRoleCurdAppService, Role, RoleCreateDto, RoleCreateDto, RoleItemDto, RolePagedInputDto, Guid>
    {
        protected readonly IRbacManager RbacManager;
        protected readonly IRbacChecker RbacChecker;

        protected RoleController(IRoleCurdAppService curdAppService, IRbacManager rbacManager, IRbacChecker rbacChecker) : base(curdAppService)
        {
            RbacManager = rbacManager;
            RbacChecker = rbacChecker;
        }

        [HttpPut]
        public override async Task<RoleItemDto> Update(RoleCreateDto dto)
        {
            if (!RbacChecker.RequireScope(dto.Api))
            {
                throw new K9UserFriendlyException(403, "没有访问权限");
            }

            return await base.Update(dto);
        }

        [HttpDelete]
        public override async Task Delete(Guid id)
        {
            var role = await CurdAppService.GetAsync(id, HttpContext.RequestAborted);

            if (role != null)
            {
                if (!RbacChecker.RequireScope(role.Api))
                {
                    throw new K9UserFriendlyException(403, "没有访问权限");
                }

                await CurdAppService.DeleteAsync(id, HttpContext.RequestAborted);
            }

        }

        [HttpGet]
        public override async Task<PagedResultDto<RoleItemDto>> List(RolePagedInputDto dto)
        {
            if (!RbacChecker.RequireScope(dto.Api))
            {
                throw new K9UserFriendlyException(403, "没有访问权限");
            }

            if (string.IsNullOrEmpty(dto.Api) || string.IsNullOrEmpty(dto.Resource))
            {
                return await base.List(dto);
            }

            var roles = await RbacManager.GetRolesInResourceAsync(dto.Api, dto.Resource, HttpContext.RequestAborted);

            var result = await CurdAppService.ListAsync(dto.Api, roles.AsArray());

            return new PagedResultDto<RoleItemDto>(result.Count, result);
        }

        [HttpGet]
        public async Task<IReadOnlyList<IApiResource>> GetApiResources(string api, string role)
        {
            if (!RbacChecker.RequireScope(api))
            {
                throw new K9UserFriendlyException(403, "没有访问权限");
            }
            var result = await RbacManager.GetResourcesInRolesAsync(api, new[] { role }, HttpContext.RequestAborted);
            return result;
        }

        [HttpPost]
        public async Task AddRoleToResources(EditRoleToResourcesDto input)
        {
            if (!RbacChecker.RequireScope(input.Api))
            {
                throw new K9UserFriendlyException(403, "没有访问权限");
            }
            await RbacManager.AddRoleToResourcesAsync(input.Api, input.Role, input.Resources,
                HttpContext.RequestAborted);
        }

        [HttpDelete]
        public async Task RemoveRoleFromResources(EditRoleToResourcesDto input)
        {
            if (!RbacChecker.RequireScope(input.Api))
            {
                throw new K9UserFriendlyException(403, "没有访问权限");
            }
            await RbacManager.RemoveRoleFromResourcesAsync(input.Api, input.Role, input.Resources,
                HttpContext.RequestAborted);
        }
    }
}